﻿using E3.CSharpZipLib.Zip;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CoreShop.App
{
    public class DownFile
    {
        string oldUpdateListXml = Application.StartupPath+ "\\UpdateListEx.xml";
        string newUpdateListXml = Application.StartupPath + "\\Temp\\UpdateListEx.xml";

        int availableUpdate = 0;
        List<Tuple<string,string>> lvUpdateList = new List<Tuple<string, string>>();

        public delegate void InitalBar(long size);
        public event InitalBar initalProgressbar;

        public delegate void SetBarProgress(long size);
        public event SetBarProgress setBarprogress;

        public delegate void CloseProgress();
        public event CloseProgress closeProgress;
        public bool CheckVersion = true;
        public delegate void setLog(string msg);
        public event setLog SetLog;


        private bool ExistsNewFile()
        {
            try
            {
                //string sql = string.Format(@"select FPosVerUpgrade from t_SystemPara where FPosVerUpgrade < {0}", SysVar.FPosVerUpgrade);
                //DataTable dt = DataHelperLocal.GetDataTable(sql);
                //if (dt == null || dt.Rows.Count == 0) return false;
                //return true;
                return false;
            }
            catch(Exception e)
            {
                return false;
            }
        }

        /// <summary>
        /// 下载升级包，升级方法：改t_DataExchange,t_Parameter.FPosVerUpgrade和UpdateListEx.xml
        /// 1、服务器的t_Parameter.FDownFileTime控制检测升级包版本号周期
        /// 2、服务器的t_Parameter.FPosVerUpgrade控制是否要对比UpdateListEx.xml文件内容(2021-01-19版本之前用FPosVersion字段，新版本不用
        /// 3、服务器的UpdateListEx.xml控制升级包是否要下载。
        /// </summary>
        public void DownLoad()
        {
            bool isUpgradeWork = false;
            try
            {
                SetLog(DateTime.Now.ToString() + "  开始检查可升级文件。\r\n");
                if (CheckVersion && !ExistsNewFile())
                {
                    if (closeProgress != null) closeProgress();
                    //MessageBox.Show("当前没有升级文件可下载");
                    SetLog(DateTime.Now.ToString() + "  当前没有升级文件可下载。\r\n");
                    return;
                }

                //下载new UpdateListXml并生成需要更新的文件列表
                CheckDownFileList();

                //根据文件列表进行下载
                DownUpdateFile();
                isUpgradeWork = true;
                SetLog("ok");
                //解压
                //Unzip();//不用，在前台登陆时解压
                //DeleteZip();//不用，在前台登陆时解压

                //文件备份
                //CopyFolder(SysVar.mCurrentPath, BackPath);//不用，在前台登陆时复制

                //下载完成等待处理 退出时有下载文件时移动文件
            }
            catch (Exception e)
            {
                SetLog(DateTime.Now.ToString() + string.Format("  升级出错001：{0}\r\n", e.Message));
                //日志
            }
            finally
            {
                MyConstVars.DownFileFlag = false;
                if (!isUpgradeWork) SetLog(DateTime.Now.ToString() + "  升级包下载完成。\r\n");
            }
        }

        private void CheckDownFileList()
        {
            AppUpdater appUpdater = new AppUpdater();
            try
            {
                appUpdater.UpdaterUrl = MyConstVars.updateUrl + "/" + MyConstVars.softName + "/UpdateListEx.xml";
                appUpdater.DownAutoUpdateFile(Application.StartupPath + "//Temp");

                Hashtable htUpdateFile = new Hashtable();
                if (!File.Exists(newUpdateListXml))
                {
                    return;
                }
                if (!File.Exists(oldUpdateListXml))
                {
                    availableUpdate = appUpdater.CheckForUpdate(newUpdateListXml, out htUpdateFile);
                }
                else
                {
                    availableUpdate = appUpdater.CheckForUpdate(newUpdateListXml, oldUpdateListXml, out htUpdateFile);
                }

                if (availableUpdate > 0)
                {
                    for (int i = 0; i < htUpdateFile.Count; i++)
                    {
                        string[] fileArray = (string[])htUpdateFile[i];
                        lvUpdateList.Add(new Tuple<string, string>(fileArray[0], fileArray[2]));
                    }
                }
            }
            catch (Exception e)
            {
                SetLog(DateTime.Now.ToString() + string.Format("  升级出错002：{0}\r\n", e.Message));
            }
            finally
            {
                appUpdater.Dispose();
            }
        }

        private void CopyFolder(string from, string to)
        {
            try
            {
                if (!Directory.Exists(to))
                    Directory.CreateDirectory(to);

                // 子文件夹
                foreach (string sub in Directory.GetDirectories(from))
                {
                    if (sub.ToLower().Substring(sub.Length - 4) != "temp")
                    {
                        CopyFolder(sub + "\\", to + System.IO.Path.GetFileName(sub) + "\\");
                    }
                }

                string mfiles = "";

                // 文件
                foreach (string file in Directory.GetFiles(from))
                {
                    mfiles = Path.GetExtension(file).ToUpper();
                    if ((mfiles != ".MDF") && (mfiles != ".LDF"))
                    {
                        File.Copy(file, to + System.IO.Path.GetFileName(file), true);
                    }
                }

                //复制updatelist.xml文件
                //File.Copy(newUpdateListXml, SysVar.mCurrentPath+ "\\UpdateListEx.xml", true);
            }
            catch (Exception e)
            {
                SetLog(DateTime.Now.ToString() + string.Format("  升级出错003：{0}\r\n", e.Message));
            }
        }

        private void DownExc_SetLog(string msg)
        {
            SetLog(msg);
        }

        private void DownUpdateFile()
        {
            bool isDown = true;
            if (this.lvUpdateList.Count == 0)
            {
                SetLog(DateTime.Now.ToString() + "  未检查到有更新的升级包。\r\n");
                Down_initalProgressbar(1);
                Down_setBarprogress(1025);
            }
            else
            {
                SetLog(DateTime.Now.ToString() + string.Format("  共检测到{0}个有更新的升级文件。\r\n", this.lvUpdateList.Count));
            }

            MyConstVars.DownFileCount = this.lvUpdateList.Count;
            MyConstVars.DownFileYes = 0;

            for (int i = 0; i < this.lvUpdateList.Count; i++)
            {
                string UpdateFile;
                string floder;
                UpdateFile = lvUpdateList[i].Item1.Trim();
                floder = lvUpdateList[i].Item2.Trim();

                try
                {
                    string mDownLoadPath = Application.StartupPath + "\\DownLoad";
                    if (System.IO.File.Exists(mDownLoadPath + "\\" + UpdateFile))
                    {
                        System.IO.File.Delete(mDownLoadPath + "\\" + UpdateFile);
                    }
                    string downloadurl = MyConstVars.updateUrl + "/" + MyConstVars.softName + "/" + UpdateFile;
                    string tmp_newPath = mDownLoadPath;
                    if (!string.IsNullOrEmpty(floder))
                    {
                        downloadurl = MyConstVars.updateUrl + "/" + MyConstVars.softName + "/" + floder + "/" + UpdateFile;
                        tmp_newPath = mDownLoadPath + "\\" + floder + "\\";
                    }
                    httpDown down = new httpDown();
                    down.initalProgressbar += Down_initalProgressbar;
                    down.setBarprogress += Down_setBarprogress;
                    down.SetLog += DownExc_SetLog;
                    down.HttpDownload(downloadurl, tmp_newPath, i + 1);
                }
                catch (Exception ex)
                {
                    isDown = false;
                    SetLog(DateTime.Now.ToString() + string.Format("  下载出错004：{0}\r\n", ex.Message));
                    return;
                }
                finally
                {

                }
            }
            if (closeProgress != null) closeProgress();
        }

        private void Down_setBarprogress(long size)
        {
            if (setBarprogress != null) setBarprogress(size);
        }

        private void Down_initalProgressbar(long size)
        {
            if (initalProgressbar != null) initalProgressbar(size);
        }

        private bool UnZipFile(string zipFilePath, string localPath)
        {
            bool result = true;
            try
            {
                if (!File.Exists(zipFilePath))
                {
                    return false;
                }
                using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)))
                {
                    ZipEntry theEntry;
                    while ((theEntry = s.GetNextEntry()) != null)
                    {
                        string fileName = Path.GetFileName(theEntry.Name);
                        if (!Directory.Exists(localPath))
                        {
                            Directory.CreateDirectory(localPath);
                        }
                        string subdir = theEntry.Name.LastIndexOf(fileName) == 0
                                            ? ""
                                            : theEntry.Name.Substring(0, theEntry.Name.LastIndexOf(fileName) - 1);

                        string filedir = localPath + @"\" + subdir;
                        if (!Directory.Exists(filedir))
                        {
                            Directory.CreateDirectory(filedir);
                        }

                        if (fileName != String.Empty)
                        {
                            using (FileStream streamWriter = File.Create(localPath + @"\" + theEntry.Name))
                            {
                                int size = 2048;
                                byte[] data = new byte[2048];
                                while (true)
                                {
                                    size = s.Read(data, 0, data.Length);
                                    if (size > 0)
                                    {
                                        streamWriter.Write(data, 0, size);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                result = false;
            }
            return result;
        }

        private bool isZip(string fileName)
        {
            bool iszip = false;
            if (fileName.Split('.').Length > 1)
            {
                if (fileName.Split('.')[1].ToLower() == "zip")
                {
                    iszip = true;
                }
            }
            return iszip;
        }


    }
}
